package org.tlipoca.smarticletagrelational.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.genntii.smcommon.constant.ExceptionConstant;
import org.genntii.smcommon.exception.ArticleTagNotFoundException;
import org.genntii.smdomain.dto.ArticleTagRelationalDTO;
import org.genntii.smdomain.entity.ArticleTagRelational;
import org.springframework.stereotype.Service;

import org.tlipoca.smarticletagrelational.client.ArticleTagClient;
import org.tlipoca.smarticletagrelational.entity.ArticleTagMap;
import org.tlipoca.smarticletagrelational.mapper.ArticleTagRelationalMapper;
import org.tlipoca.smarticletagrelational.service.ArticleTagRelationalService;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.stream.Stream;

@Slf4j
@Service
public class ArticleTagRelationalServiceImpl extends ServiceImpl<ArticleTagRelationalMapper, ArticleTagRelational> implements ArticleTagRelationalService {

    @Resource
    private ArticleTagRelationalMapper articleTagRelationalMapper;

    @Resource
    private ArticleTagClient articleTagClient;

    @Override
    public ArrayList<ArticleTagRelational> getArticleTagRelationalByArticleIdService(Long articleId) {
        return articleTagRelationalMapper.selectArticleTagIdByArticleId(articleId);
    }


    @Override
    public void addArticleTagRelationalService(ArticleTagRelationalDTO articleTagRelationalDTO) {
        if (!articleTagClient.articleTagListExists(articleTagRelationalDTO.getTagIds()).getData()){
            throw new ArticleTagNotFoundException(ExceptionConstant.ARTICLE_TAG_NOT_FOUND_EXCEPTION);
        }
        ArrayList<ArticleTagRelational> articleTagRelationals = articleTagRelationalMapper.selectArticleTagIdByArticleId(articleTagRelationalDTO.getArticleId());
        if (Stream.concat(articleTagRelationals.stream(), articleTagRelationalDTO.getTagIds().stream()).distinct().findAny().isEmpty()){
            //TODO use a better Exception
            throw new ArticleTagNotFoundException(ExceptionConstant.ARTICLE_TAG_DUPLICATES_EXCEPTION);
        }

        articleTagRelationalMapper.insertArticleTagRelationalBatch(articleTagRelationalDTO);
    }

    @Override
    public void updateArticleTagRelationalService(ArticleTagRelationalDTO articleTagRelationalDTO) {
        if (!articleTagClient.articleTagListExists(articleTagRelationalDTO.getTagIds()).getData()){
            throw new ArticleTagNotFoundException(ExceptionConstant.ARTICLE_TAG_NOT_FOUND_EXCEPTION);
        }
        ArrayList<ArticleTagRelational> articleTagRelationals = articleTagRelationalMapper.selectArticleTagIdByArticleId(articleTagRelationalDTO.getArticleId());
        if (Stream.concat(articleTagRelationals.stream(), articleTagRelationalDTO.getTagIds().stream()).distinct().findAny().isEmpty()){
            //TODO use a better Exception
            throw new ArticleTagNotFoundException(ExceptionConstant.ARTICLE_TAG_DUPLICATES_EXCEPTION);
        }
        articleTagRelationalMapper.deleteArticleTagRelationalBatch(articleTagRelationalDTO.getArticleId());
        articleTagRelationalMapper.insertArticleTagRelationalBatch(articleTagRelationalDTO);
    }

    @Override
    public void deleteArticleTagRelationalService(ArticleTagRelationalDTO articleTagRelationalDTO) {
        if (!articleTagClient.articleTagListExists(articleTagRelationalDTO.getTagIds()).getData()){
            throw new ArticleTagNotFoundException(ExceptionConstant.ARTICLE_TAG_NOT_FOUND_EXCEPTION);
        }
        articleTagRelationalMapper.deleteArticleTagRelational(articleTagRelationalDTO);
    }

    @Override
    public void deleteArticleTagRelationalBatch(Long articleId) {
        articleTagRelationalMapper.deleteArticleTagRelationalBatch(articleId);
    }

    @Override
    public Map<String , ArrayList<Long>> getTagIdsByArticleIds(ArrayList<Long> articleIds) {

        List<ArticleTagMap> articleTagMapList = articleTagRelationalMapper.getTagListMapByArticleIds(articleIds);
        Map<String , ArrayList<Long>> articleTagMap = new TreeMap<>();

        for (ArticleTagMap item : articleTagMapList) {
            articleTagMap.put(String.valueOf(item.getArticleId()), item.getTagIds());
        }

        return articleTagMap;
    }
}
